#include "websocket/ws_client.hpp"
#include <boost/beast/websocket.hpp>
#include <iostream>

using namespace WD;
using tcp = boost::asio::ip::tcp;
namespace websocket = boost::beast::websocket;

// 构造函数初始化，连接状态设为断开
WebSocketClient::WebSocketClient(boost::asio::io_context& ioc)
    : ioc_(ioc),
      resolver_(ioc),
      ws_(ioc),
      running_(false),
      status_(Status::Disconnected) {}

WebSocketClient::~WebSocketClient() {
    close();
}

// 连接 WebSocket 服务端（host: 地址，port: 端口，path: 路径）
bool WebSocketClient::connect(const std::string& host, const std::string& port, const std::string& path) {
    try {
        status_ = Status::Connecting;
        // DNS 解析域名得到服务器地址
        auto const results = resolver_.resolve(host, port);
        // 建立 TCP 连接
        boost::asio::connect(ws_.next_layer(), results.begin(), results.end());

         // 进行 WebSocket 握手，path 通常为 "/" 或具体路径
        ws_.handshake(host, path);
        status_ = Status::Open;

        // 启动读线程，异步接收消息
        running_ = true;
        reader_ = std::thread([this]() { readLoop(); });

        return true;
    } catch (const std::exception& e) {
        std::cerr << "[connect] Exception: " << e.what() << std::endl;
        status_ = Status::Failed;
        return false;
    }
}

// 发送消息（同步发送，线程安全由调用者保障）
void WebSocketClient::send(const std::string& message) {
    if (status_.load() != Status::Open) return;

    try {
        ws_.write(boost::asio::buffer(message));
    } catch (const std::exception& e) {
        std::cerr << "[send] Exception: " << e.what() << std::endl;
    }
}

// 读取消息队列中的第一条消息（线程安全）
std::string WebSocketClient::receive() {
    std::lock_guard<std::mutex> lock(msg_mutex_);
    if (msg_queue_.empty()) return "";
    std::string msg = std::move(msg_queue_.front());
    msg_queue_.pop();
    return msg;
}

// 接收线程执行函数：不断从服务器读取消息，并加入消息队列
void WebSocketClient::readLoop() {
    try {
        while (running_) {
            boost::beast::flat_buffer buffer;
            boost::system::error_code ec;
            ws_.read(buffer, ec);

            if (ec == websocket::error::closed) {
                std::cout << "[readLoop] WebSocket closed cleanly." << std::endl;
                break;
            } else if (ec) {
                std::cerr << "[readLoop] Read error: " << ec.message() << std::endl;
                break;
            }
            std::string msg = boost::beast::buffers_to_string(buffer.data());
            {
                std::lock_guard<std::mutex> lock(msg_mutex_);
                msg_queue_.push(std::move(msg));
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "[readLoop] Exception: " << e.what() << std::endl;
    }
}


void WebSocketClient::close() {
    running_ = false;
    try {
        if (status_.load() == Status::Open) {
            ws_.close(websocket::close_code::normal);
            
        }
    } catch (...) {}

    
    if (reader_.joinable()) {
        reader_.join();
    }

    status_ = Status::Closed;
}

// 获取当前连接状态
WebSocketClient::Status WebSocketClient::getStatus() const {
    return status_;
}